#!/usr/bin/env python
# _*_coding:utf-8_*_
'''
 * Created on 2016/11/7 21:24.
 * @author: Chinge_Yang.
'''

import shutil
import json


def list_function():
    print("Please choice the ID of a action.".center(50, "#"))
    print("【1】.Fetch haproxy.cfg backend infomation.")
    print("【2】.Add haproxy.cfg backend infomation.")
    print("【3】.Delete haproxy.cfg backend infomation.")
    print("End".center(50, "#"))


def fetch(backend):
    # 取出backend相关server信息
    result = []  # 定义结果列表
    with open("haproxy.cfg", "r", encoding="utf-8") as f:  # 循环读取文件
        flag = False  # 标记为假
        for line in f:
            # 以backend开头
            line = line.strip()
            if line.startswith("backend") and line == "backend " + backend:
                flag = True  # 读取到backend开头的信息，标记为真
                continue
            # 下一个backend开头
            if flag and line.strip().startswith("backend"):
                flag = False
                break
            # server信息添加到result列表
            if flag and line.strip():
                result.append(line.strip())
    return result


def writer(backend, record_list):
    with open("haproxy.cfg", "r") as old, open("new.cfg", "w") as new:
        flag = False
        for line in old:
            if line.strip().startswith('backend') and line.strip() == "backend " + backend:
                flag = True
                new.write(line)
                for new_line in record_list:
                    new.write(" " * 4 + new_line + "\n")
                continue  # 跳到下一次循环，避免下一个backend写二次

            if flag and line.strip().startswith("backend"):  # 下一个backend
                flag = False
                new.write(line)
                continue  # 退出此循环，避免server信息二次写入
            if line.strip() and not flag:
                new.write(line)


def add(backend, record):
    global change_flag
    record_list = fetch(backend)  # 查找是否存在记录
    if not record_list:  # backend不存在, record不存在
        with open('haproxy.cfg', 'r') as old, open('new.cfg', 'w') as new:
            for line in old:
                new.write(line)
            # 添加新记录
            new.write("\nbackend " + backend + "\n")
            new.write(" " * 4 + record + "\n")
        print("\033[32;1mAdd done\033[0m")
        change_flag = True
    else:  # backend存在，record存在
        if record in record_list:
            print("\033[31;1mRecord already in it,Nothing to do!\033[0m")
            change_flag = False
        else:  # backend存在，record不存在
            record_list.append(record)
            writer(backend, record_list)
            print("\033[32;1mAdd done\033[0m")
            change_flag = True


def delete(backend, record):
    global change_flag
    record_list = fetch(backend)  # 查找是否存在记录
    if not record_list:  # backend不存在, record不存在
        print("Not match the backend,no need delete!".center(50, "#"))
        change_flag = False
    else:  # backend存在，record存在
        if record in record_list:
            record_list.remove(record)  # 移除元素
            writer(backend, record_list)  # 写入
            print("\033[31;1mDelete done\033[0m")
            change_flag = True
        else:  # backend存在，record不存在
            print("Only match backend,no need delete!".center(50, "#"))
            change_flag = False
    return change_flag


def output(servers):
    # 输出指定backend的server信息
    print("Match the server info:".center(50, "#"))
    for server in servers:
        print("\033[32;1m%s\033[0m" % server)
    print("#".center(50, "#"))


def input_json():
    # 判断输入，要求为json格式
    continue_flag = False
    while continue_flag is not True:
        backend_record = input("Input backend info(json):").strip()
        try:
            backend_record_dict = json.loads(backend_record)
        except Exception as e:
            print("\033[31;1mInput not a json data type!\033[0m")
            continue
        continue_flag = True
    return backend_record_dict


def operate(action):
    global change_flag
    if action == "fetch":
        backend_info = input("Input backend info:").strip()
        result = fetch(backend_info)  # 取出backend信息
        if result:
            output(result)  # 输出获取到的server信息
        else:
            print("\033[31;1mNot a match is found!\033[0m")
    elif action is None:
        print("\033[31;1mNothing to do!\033[0m")
    else:
        backend_record_dict = input_json()  # 要求输入json格式
        for key in backend_record_dict:
            backend = key
            record = backend_record_dict[key]
            if action == "add":
                add(backend, record)
            elif action == "delete":
                delete(backend, record)
        if change_flag is True:  # 文件有修改，才进行文件更新
            # 将操作结果生效
            shutil.copy("haproxy.cfg", "old.cfg")
            shutil.copy("new.cfg", "haproxy.cfg")
            result = fetch(backend)
            output(result)  # 输出获取到的server信息


def judge_input():
    # 判断输入功能编号，执行相应步骤
    input_info = input("Your input number:").strip()
    if input_info == "1":  # 查询指定backend记录
        action = "fetch"
    elif input_info == "2":  # 添加backend记录
        action = "add"
    elif input_info == "3":  # 删除backend记录
        action = "delete"
    elif input_info == "q" or input_info == "quit":
        exit("Bye,thanks!".center(50, "#"))
    else:
        print("\033[31;1mInput error!\033[0m")
        action = None
    return action


def main():
    exit_flag = False
    while exit_flag is not True:
        global change_flag
        change_flag = False
        list_function()
        action = judge_input()
        operate(action)


if __name__ == '__main__':
    main()
